package com.basic.nio;

import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @Author: wisdom
 * @Date: 2024/3/30  9:04 PM
 * @Description:
 *
 * capacity()返回此缓冲区的容量。
 * position()返回此缓冲区的位置。
 * limit()返回此缓冲区的限制。
 * mark()将此缓冲区的标记设置在其位置。
 * reset()将此缓冲区的位置重置为先前标记的位置。调用此方法既不会更改也不丢弃该标记的值。
 * clear()清除此缓冲区。 位置设置为零，限制设置为容量，标记被丢弃。
 * flip()翻转这个缓冲区。 该限制设置为当前位置，然后将该位置设置为零。 如果标记被定义，则它被丢弃。
 * rewind()倒带这个缓冲区。 位置设置为零，标记被丢弃。
 * remaining()返回当前位置和限制之间的元素数。
 * hasRemaining()告诉当前位置和极限之间是否存在任何元素。
 */
public class BufferTest {

    /**
     * 直接缓冲区
     */
    @Test
    public void directTest() throws Exception {
        FileInputStream fis = new FileInputStream("data.txt");
        FileChannel fisChannel = fis.getChannel();

        FileOutputStream fos = new FileOutputStream("data2.txt");
        FileChannel fosChannel = fos.getChannel();

        ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

        while (buffer.hasRemaining()){
            buffer.clear();
            fisChannel.read(buffer);
            buffer.flip();
            fosChannel.write(buffer);
        }
    }
    /**
     * 只读缓冲区
     */
    @Test
    public void readTest(){
        ByteBuffer buffer = ByteBuffer.allocate(10);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put((byte) i);
        }

        //创建只读缓冲区
        ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer();
        for (int i = 0; i < buffer.capacity(); i++) {
            byte b = buffer.get(i);
            b *= 10;
            buffer.put(i,b);
        }
        readOnlyBuffer.position(0);
        readOnlyBuffer.limit(buffer.capacity());
        while (readOnlyBuffer.hasRemaining()){
            System.out.println(readOnlyBuffer.get());
        }
    }


    /**
     * 缓冲区分片
     */
    @Test
    public void sliceTest(){
        ByteBuffer buffer = ByteBuffer.allocate(10);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put((byte) i);
        }
        //创建子缓冲区
        buffer.position(3);
        buffer.limit(7);
        ByteBuffer slice = buffer.slice();
        for (int i = 0; i < slice.capacity(); i++) {
            byte b = slice.get(i);
            b *= 10;
            slice.put(i,b);
        }
        buffer.position(0);
        buffer.limit(buffer.capacity());
        while (buffer.hasRemaining()){
            System.out.println(buffer.get());
        }

    }

    @Test
    public void buffer3(){
        //allocateDirect-直接内存  allocate-非直接内存(堆内存)
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);
        System.out.println(byteBuffer.isDirect());
    }

    @Test
    public void buffer2(){
//        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
//        System.out.println(byteBuffer.position());// 0
//        System.out.println(byteBuffer.limit());// 10
//        System.out.println(byteBuffer.capacity());// 10
//
//        System.out.println("------------");
//        //put 缓冲区添加数据
//        String name = "wangzhi";
//        byteBuffer.put(name.getBytes());
//        System.out.println(byteBuffer.position());// 7
//        System.out.println(byteBuffer.limit());// 10
//        System.out.println(byteBuffer.capacity());// 10
//
//        System.out.println("------------");
//        //clear 清除缓冲区的数据
//        byteBuffer.clear();
//        System.out.println(byteBuffer.position());// 0
//        System.out.println(byteBuffer.limit());// 10
//        System.out.println(byteBuffer.capacity());// 10
//        System.out.println((char)byteBuffer.get());
//        byteBuffer.put("zhang".getBytes());
//
//        System.out.println("------------");
//
//        System.out.println(byteBuffer.position());// 0
//        System.out.println(byteBuffer.limit());// 10
//        System.out.println(byteBuffer.capacity());// 10
//        System.out.println((char)byteBuffer.get());
//        System.out.println("------------");

        ByteBuffer buffer = ByteBuffer.allocate(10);
        String n = "wangzhi";
        buffer.put(n.getBytes());
        System.out.println(buffer.position());// 7
        System.out.println(buffer.limit());// 7
        System.out.println(buffer.capacity());// 10
        System.out.println("------------");
        buffer.flip();
        byte[] b = new byte[2];
        buffer.get(b);
        System.out.println(new String(b));
        System.out.println(buffer.position());// 2
        System.out.println(buffer.limit());// 7
        System.out.println(buffer.capacity());// 10
        System.out.println("------------");
        buffer.mark();
        byte[] b2 = new byte[3];
        buffer.get(b2);
        System.out.println(new String(b2));
        System.out.println(buffer.position());// 5
        System.out.println(buffer.limit());// 7
        System.out.println(buffer.capacity());// 10

        System.out.println("------------");
        buffer.reset();
        System.out.println(buffer.position());// 2
        System.out.println(buffer.limit());// 7
        System.out.println(buffer.capacity());// 10


        if(buffer.hasRemaining()){
            System.out.println("------------");
            System.out.println(buffer.remaining());
        }
    }

    @Test
    public void buffer1(){
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        System.out.println(byteBuffer.position());// 0
        System.out.println(byteBuffer.limit());// 10
        System.out.println(byteBuffer.capacity());// 10

        System.out.println("------------");

        String name = "wangzhi";
        byteBuffer.put(name.getBytes());
        System.out.println(byteBuffer.position());// 7
        System.out.println(byteBuffer.limit());// 10
        System.out.println(byteBuffer.capacity());// 10

        System.out.println("------------");

        byteBuffer.flip();
        System.out.println(byteBuffer.position());// 0
        System.out.println(byteBuffer.limit());// 7
        System.out.println(byteBuffer.capacity());// 10

        System.out.println("------------");
        char c = (char)byteBuffer.get();
        System.out.println(c);
        System.out.println(byteBuffer.position());//1
        System.out.println(byteBuffer.limit());//7
        System.out.println(byteBuffer.capacity());//10
    }
}
